package com.ruoyi.web.controller.order.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ruoyi.common.constant.*;
import com.ruoyi.common.entity.DO.member.MemberBalanceRecordDO;
import com.ruoyi.common.entity.DO.member.MemberCouponDO;
import com.ruoyi.common.entity.DO.member.MemberCreditRecordDO;
import com.ruoyi.common.entity.DO.member.MemberDO;
import com.ruoyi.common.entity.DO.order.*;
import com.ruoyi.common.entity.VO.member.MemberGetCreditProductVO;
import com.ruoyi.common.entity.VO.order.*;
import com.ruoyi.common.entity.VO.shop.ShopProductSearchVO;
import com.ruoyi.common.entity.VO.shop.ShopProductVO;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.mapper.IBackShopProductMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberBalanceRecordMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberCouponMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberCreditRecordMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberMapper;
import com.ruoyi.web.controller.order.mapper.*;
import com.ruoyi.web.controller.order.service.IBackOrderService;
import com.ruoyi.web.controller.shop.mapper.IBackShopProductCouponLinkMapper;
import com.ruoyi.web.controller.tool.IdWorker;
import lombok.Synchronized;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service("IBackOrderService")
public class BackOrderServiceImpl implements IBackOrderService {

    @Resource
    private IBackOrderMapper backOrderMapper;

    @Resource
    private IBackMemberRechargeOrderMapper rechargeOrderMapper;

    @Resource
    private IBackShopPetrolOrderMapper petrolOrderMapper;

    @Resource
    private IBackCreditOrderMapper creditOrderMapper;

    @Resource
    private IBackShopOrderStatusMapper backShopOrderStatusMapper;

    @Resource
    private IBackOrderRefundMapper backOrderRefundMapper;

    @Resource
    private IBackMemberCouponMapper backMemberCouponMapper;

    @Resource
    private IBackMemberMapper backMemberMapper;

    @Resource
    private IBackMemberBalanceRecordMapper backMemberBalanceRecordMapper;

    @Resource
    private IBackMemberCreditRecordMapper backMemberCreditRecordMapper;

    @Resource
    private IBackCreditOrderMapper backCreditOrderMapper;

    @Resource
    private IBackMemberRechargeOrderMapper backMemberRechargeOrderMapper;

    @Resource
    private IBackShopProductMapper backShopProductMapper;

    @Resource
    private IBackShopProductCouponLinkMapper backShopProductCouponLinkMapper;

    @Override
    public List<ShopOrderVO> searchList(ShopOrderSearchVO shopOrderSearchVO) {
        shopOrderSearchVO.setIsDelete(0);
        List<ShopOrderVO> orderList;
        if (SysConfigConstants.SystemModuleEnum.RECHARGE.getValue() == shopOrderSearchVO.getSystemModule()) {
            //获取充值订单列表
            orderList = backOrderMapper.searchList(shopOrderSearchVO);
        } else if (SysConfigConstants.SystemModuleEnum.PETROL.getValue() == shopOrderSearchVO.getSystemModule()) {
            orderList = backOrderMapper.searchList(shopOrderSearchVO);
        } else {
            orderList = backOrderMapper.searchList(shopOrderSearchVO);
        }
        return orderList;
    }

    @Override
    public List<MemberRechargeOrderVO> searchRechargeList(ShopOrderSearchVO shopOrderSearchVO) {
        shopOrderSearchVO.setIsDelete(0);
        List<MemberRechargeOrderVO> orderList = rechargeOrderMapper.searchList(shopOrderSearchVO);
        if(orderList.size()>0){
            orderList.forEach(x->{
                if(null!=x.getGiftAmount()){
                    x.setRealAmount(x.getAmount().add(BigDecimal.valueOf(x.getGiftAmount())));
                }else{
                    x.setGiftAmount(0);
                    x.setRealAmount(x.getAmount());
                }
            });
        }
        return orderList;
    }

    @Override
    public List<ShopPetrolOrderVO> searchPetrolList(ShopOrderSearchVO shopOrderSearchVO) {
        shopOrderSearchVO.setIsDelete(0);
        List<ShopPetrolOrderVO> orderList = petrolOrderMapper.searchList(shopOrderSearchVO);
        return orderList;
    }

    @Override
    public List<ShopCreditOrderVO> searchCreditList(ShopOrderSearchVO shopOrderSearchVO) {
        shopOrderSearchVO.setIsDelete(0);
        List<ShopCreditOrderVO> orderList = creditOrderMapper.searchList(shopOrderSearchVO);
        return orderList;
    }


    @Override
    public List<ShopOrderExportVO> searchShopOrderExportList(ShopOrderSearchVO shopOrderSearchVO) {
        return backOrderMapper.searchShopOrderExportList(shopOrderSearchVO);
    }

    @Override
    public List<OrderExportVO> searchOrderExportList(ShopOrderSearchVO shopOrderSearchVO) {
        List<OrderExportVO> orderExportVOList = backOrderMapper.searchOrderExportList(shopOrderSearchVO);
        if (orderExportVOList.size() > 0) {
            for (OrderExportVO one : orderExportVOList
            ) {
                JSONArray jsonArray = JSON.parseArray(one.getProductAttr());
                one.setProductAttr(jsonArray.getJSONObject(0).getString("value"));
            }
//                OrderExportVO one = new OrderExportVO();
//                orderSn = orderExportVOList.get(i).getOrderSn();
//                if(i+1 < orderExportVOList.size() && !orderSn.equals(orderExportVOList.get(i + 1).getOrderSn())){
//                    BeanUtils.copyProperties(orderExportVOList.get(i),one);
//                }else{
//                    one.setProductSkuCode(orderExportVOList.get(i).getProductSkuCode());
//                    one.setProductName(orderExportVOList.get(i).getProductName());
//                    one.setProductSkuPrice(orderExportVOList.get(i).getProductSkuPrice());
//                    one.setProductQuantity(orderExportVOList.get(i).getProductQuantity());
//                    one.setTotalPrice(orderExportVOList.get(i).getTotalPrice());
//                    one.setProductAttr(orderExportVOList.get(i).getProductAttr());
//                }
//                returnList.add(one);
//            }
        }
        return orderExportVOList;
    }

    @Override
    @Transactional
    @Synchronized
    public String rechargeCancel(String orderSn) {
        String refundSn = "";
        Example example = new Example(ShopOrderDO.class);
        example.createCriteria().andEqualTo("orderSn", orderSn);
        MemberRechargeOrderDO orderInfo = rechargeOrderMapper.selectOneByExample(example);
        if (orderInfo == null || orderInfo.getIsDelete() == 1) {
            throw new BusinessException("订单不存在，无法操作退款！");
        }
        //判断订单状态
        switch (OrderConstants.OrderStatusEnum.match(orderInfo.getOrderStatus())) {
            case CANCEL:
                //已取消
                throw new BusinessException("订单已取消，请勿重复操作！");
            case PRE_PAY:
                //待支付
                break;
            case COMPLETE:
                //已完成
                MemberDO memberInfo = backMemberMapper.selectByPrimaryKey(orderInfo.getMemberId());
                if (memberInfo.getBalance().compareTo(orderInfo.getAmount()) < 0) {
                    //TODO:判断会员当前余额是否足够回滚
                    throw new BusinessException("会员已使用充值的余额，无法操作退款！");
                }
                if (memberInfo.getBalance().compareTo(BigDecimal.valueOf(orderInfo.getGiftAmount()).add(orderInfo.getAmount())) < 0) {
                    //TODO:判断会员当前余额包含赠送的金额 是否足够回滚
                    throw new BusinessException("会员已使用充值赠送的余额，无法操作退款！");
                }
                if (memberInfo.getCredit() < orderInfo.getGiftCredit()) {
                    //TODO:判断会员当前积分是否足够回滚
                    throw new BusinessException("会员已使用充值赠送的积分，无法操作退款！");
                }
                OrderRefundDO memberRefund = new OrderRefundDO();
                memberRefund.setShopId(orderInfo.getShopId());
                memberRefund.setOrderType(OrderConstants.RefundOrderTypeEnum.MEMBER_RECHARGE_ORDER.getValue());
                memberRefund.setRefundType(0);
                memberRefund.setRefundStatus(OrderConstants.RefundStatusEnum.PRE_REFUND.getValue());
                memberRefund.setRefundSn(OrderConstants.SnPrefix.CANCEL_SHOP.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
                memberRefund.setRefundOrderSn(orderSn);
                memberRefund.setRefundPaySn(orderInfo.getPaySn());
                memberRefund.setOrderPayCost(orderInfo.getPayAmount());
                memberRefund.setRefundAmount(orderInfo.getPayAmount());
                memberRefund.setMemberId(orderInfo.getMemberId());
                memberRefund.setCreateBy(ShiroUtils.getSysUser().getLoginName());
                memberRefund.setCreateTime(new Date());
                backOrderRefundMapper.insertSelective(memberRefund);
                refundSn = memberRefund.getRefundSn();
                //TODO:扣除余额
                MemberDO memberUpdate = new MemberDO();
                memberUpdate.setId(memberInfo.getId());
                memberUpdate.setBalance(memberInfo.getBalance().subtract(orderInfo.getAmount()));
                memberUpdate.setTotalRechargeAmount(memberInfo.getTotalRechargeAmount().subtract(orderInfo.getAmount()));
                //TODO:余额变动记录
                MemberBalanceRecordDO memberBalanceRecordDO = new MemberBalanceRecordDO();
                memberBalanceRecordDO.setShopId(orderInfo.getShopId());
                memberBalanceRecordDO.setMemberId(orderInfo.getMemberId());
                memberBalanceRecordDO.setRecordSn(OrderConstants.SnPrefix.BALANCE_MEMBER.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
                memberBalanceRecordDO.setType(MemberRechargeConstants.TypeEnum.SYSTEM_INSERT.getValue());
                memberBalanceRecordDO.setChangeType(MemberRechargeConstants.ChangeTypeEnum.DECREASE.getValue());
                memberBalanceRecordDO.setLinkModel(MemberRechargeConstants.LinkModelEnum.ORDER_REFUND.getValue());
                memberBalanceRecordDO.setLinkSn(orderInfo.getPaySn());
                memberBalanceRecordDO.setOldBalance(memberInfo.getBalance());
                memberBalanceRecordDO.setChangeBalance(orderInfo.getAmount());
                memberBalanceRecordDO.setCreateBy("取消订单退款");
                memberBalanceRecordDO.setCreateTime(new Date());
                memberBalanceRecordDO.setNewBalance(memberUpdate.getBalance());
                memberBalanceRecordDO.setRemark("订单退款成功,余额扣除:" + orderInfo.getAmount() + "元"
                        + "，帐号余额：" + memberUpdate.getBalance() + "元"
                        + "，退款单号：" + memberRefund.getRefundSn());
                backMemberBalanceRecordMapper.insertSelective(memberBalanceRecordDO);
                if (orderInfo.getGiftCredit() > 0) {
                    //TODO:扣除赠送积分
                    memberUpdate.setCredit(memberInfo.getCredit() - orderInfo.getGiftCredit());
                    //TODO:积分变动记录
                    MemberCreditRecordDO memberCreditRecordDO = new MemberCreditRecordDO();
                    memberCreditRecordDO.setShopId(orderInfo.getShopId());
                    memberCreditRecordDO.setRecordSn(OrderConstants.SnPrefix.CREDIT_MEMBER.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
                    memberCreditRecordDO.setType(MemberCreditConstants.TypeEnum.SYSTEM_INSERT.getValue());
                    memberCreditRecordDO.setChangeType(MemberCreditConstants.ChangeTypeEnum.DECREASE.getValue());
                    memberCreditRecordDO.setLinkModel(MemberCreditConstants.LinkModelEnum.RECHARGE_CANCEL.getValue());
                    memberCreditRecordDO.setLinkSn(orderInfo.getOrderSn());
                    memberCreditRecordDO.setMemberId(orderInfo.getMemberId());
                    memberCreditRecordDO.setOldCredit(memberInfo.getCredit());
                    memberCreditRecordDO.setChangeCredit(orderInfo.getGiftCredit());
                    memberCreditRecordDO.setNewCredit(memberUpdate.getCredit());
                    memberCreditRecordDO.setRemark("会员充值订单退款,退款:" + orderInfo.getAmount() + "元"
                            + "，扣除：" + orderInfo.getGiftCredit() + "分"
                            + "，退款单号：" + memberRefund.getRefundSn());
                    memberCreditRecordDO.setCreateBy("会员充值订单退款扣除积分");
                    memberCreditRecordDO.setCreateTime(new Date());
                    backMemberCreditRecordMapper.insertSelective(memberCreditRecordDO);
                }
                backMemberMapper.updateByPrimaryKeySelective(memberUpdate);
                orderInfo.setPayStatus(OrderConstants.OrderPayStatusEnum.PRE_REFUND.getValue());
                break;
            default:
                throw new BusinessException("当前订单状态无法取消，如有需要，请联系客服处理！");
        }
        orderInfo.setOrderStatus(OrderConstants.OrderStatusEnum.CANCEL.getValue());
        orderInfo.setCancelTime(new Date());
        rechargeOrderMapper.updateByPrimaryKeySelective(orderInfo);
        return refundSn;
    }

    @Override
    @Transactional
    @Synchronized
    public String petrolCancel(String orderSn) {
        String refundSn = "";
        Example example = new Example(ShopOrderDO.class);
        example.createCriteria().andEqualTo("orderSn", orderSn);
        ShopPetrolOrderDO orderInfo = petrolOrderMapper.selectOneByExample(example);
        if (orderInfo == null || orderInfo.getIsDelete() == 1) {
            throw new BusinessException("订单不存在，无法操作退款！");
        }
        //判断订单状态
        switch (OrderConstants.OrderStatusEnum.match(orderInfo.getOrderStatus())) {
            case CANCEL:
                //已取消
                throw new BusinessException("订单已取消，请勿重复操作！");
            case PRE_PAY:
                //待支付
                break;
            case COMPLETE:
                //已完成
                MemberDO memberInfo = backMemberMapper.selectByPrimaryKey(orderInfo.getMemberId());
                if (memberInfo.getCredit() < orderInfo.getGiftCredit()) {
                    //TODO:判断会员当前积分是否足够回滚
                    throw new BusinessException("会员已使用充值赠送的积分，无法操作退款！");
                }
                MemberDO memberUpdate = new MemberDO();
                memberUpdate.setId(memberInfo.getId());
                //TODO:判断是否微信支付，微信支付需要回退累计加油金额
                if (OrderConstants.OrderPayWayEnum.WX_PAY.getValue() == orderInfo.getPayWay()) {
                    memberUpdate.setTotalPetrolAmount(memberInfo.getTotalPetrolAmount().subtract(orderInfo.getPayCost()));
                }
                OrderRefundDO memberRefund = new OrderRefundDO();
                memberRefund.setShopId(orderInfo.getShopId());
                memberRefund.setMemberId(orderInfo.getMemberId());
                memberRefund.setOrderType(OrderConstants.RefundOrderTypeEnum.PETROL_ORDER.getValue());
                memberRefund.setRefundType(0);
                memberRefund.setRefundWay(orderInfo.getPayWay());
                memberRefund.setRefundStatus(OrderConstants.RefundStatusEnum.PRE_REFUND.getValue());
                memberRefund.setRefundSn(OrderConstants.SnPrefix.CANCEL_SHOP.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
                memberRefund.setRefundOrderSn(orderSn);
                memberRefund.setRefundPaySn(orderInfo.getPaySn());
                memberRefund.setOrderPayCost(orderInfo.getPayCost());
                memberRefund.setRefundAmount(orderInfo.getPayCost());
                memberRefund.setCreateBy(ShiroUtils.getSysUser().getLoginName());
                memberRefund.setCreateTime(new Date());
                backOrderRefundMapper.insertSelective(memberRefund);
                refundSn = memberRefund.getRefundSn();
                if (orderInfo.getGiftCredit() > 0) {
                    //TODO:扣除赠送积分
                    memberUpdate.setCredit(memberInfo.getCredit() - orderInfo.getGiftCredit());
                    //TODO:积分变动记录
                    MemberCreditRecordDO memberCreditRecordDO = new MemberCreditRecordDO();
                    memberCreditRecordDO.setShopId(orderInfo.getShopId());
                    memberCreditRecordDO.setRecordSn(OrderConstants.SnPrefix.CREDIT_MEMBER.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
                    memberCreditRecordDO.setType(MemberCreditConstants.TypeEnum.SYSTEM_INSERT.getValue());
                    memberCreditRecordDO.setChangeType(MemberCreditConstants.ChangeTypeEnum.DECREASE.getValue());
                    memberCreditRecordDO.setLinkModel(MemberCreditConstants.LinkModelEnum.PETROL_CANCEL.getValue());
                    memberCreditRecordDO.setLinkSn(orderInfo.getOrderSn());
                    memberCreditRecordDO.setMemberId(orderInfo.getMemberId());
                    memberCreditRecordDO.setOldCredit(memberInfo.getCredit());
                    memberCreditRecordDO.setChangeCredit(orderInfo.getGiftCredit());
                    memberCreditRecordDO.setNewCredit(memberUpdate.getCredit());
                    memberCreditRecordDO.setRemark("会员加油订单退款,退款:" + orderInfo.getPayCost() + "元"
                            + "，扣除：" + orderInfo.getGiftCredit() + "分"
                            + "，退款单号：" + memberRefund.getRefundSn());
                    memberCreditRecordDO.setCreateBy("会员加油订单退款扣除积分");
                    memberCreditRecordDO.setCreateTime(new Date());
                    backMemberCreditRecordMapper.insertSelective(memberCreditRecordDO);
                }
                memberUpdate.setUpdateTime(new Date());
                backMemberMapper.updateByPrimaryKeySelective(memberUpdate);
                orderInfo.setPayStatus(OrderConstants.OrderPayStatusEnum.PRE_REFUND.getValue());
                break;
            default:
                throw new BusinessException("当前订单状态无法取消，如有需要，请联系客服处理！");
        }
        orderInfo.setOrderStatus(OrderConstants.OrderStatusEnum.CANCEL.getValue());
        orderInfo.setCancelTime(new Date());
        petrolOrderMapper.updateByPrimaryKeySelective(orderInfo);
        //TODO:退优惠券
        if (0 != orderInfo.getCouponId()) {
            backMemberCouponMapper.cancelRollBack(orderInfo.getMemberId(), orderInfo.getCouponId());
            AsyncManager.me().execute(AsyncFactory.refreshCoupon(orderInfo.getCouponId().toString()));
        }
        return refundSn;
    }

    @Override
    public ShopOrderVO getDetailByOrderSn(String sn) {
        Example example = new Example(ShopOrderDO.class);
        if (sn.startsWith(OrderConstants.SnPrefix.PETROL.getValue())) {
            example.createCriteria().andEqualTo("orderSn", sn);
        } else {
            example.createCriteria().andEqualTo("orderBackSn", sn);
        }
        ShopOrderDO shopOrderDO = backOrderMapper.selectOneByExample(example);
        if (shopOrderDO == null || shopOrderDO.getIsDelete() == 1) {
            throw new BusinessException("没有此订单！");
        }
        example = new Example(ShopOrderStatusDO.class);
        example.createCriteria().andEqualTo("orderSn", shopOrderDO.getOrderSn());
        ShopOrderStatusDO shopOrderStatusDO = backShopOrderStatusMapper.selectOneByExample(example);
        ShopOrderVO shopOrderVO = new ShopOrderVO();
        BeanUtils.copyProperties(shopOrderDO, shopOrderVO);
        shopOrderVO.setOrderStatus(shopOrderStatusDO.getOrderStatus());
        shopOrderVO.setPayStatus(shopOrderStatusDO.getPayStatus());
        shopOrderVO.setShopPayStatus(shopOrderStatusDO.getShopPayStatus());
        return shopOrderVO;
    }

    @Override
    public ShopCreditOrderDO getDetailByExchangeCode(String exchangeCode) {
        Example example = new Example(ShopCreditOrderDO.class);
        example.createCriteria().andEqualTo("exchangeCode", exchangeCode);
        ShopCreditOrderDO shopCreditOrderDO = creditOrderMapper.selectOneByExample(example);
        if (shopCreditOrderDO == null || shopCreditOrderDO.getIsDelete() == 1) {
            throw new BusinessException("没有此订单！");
        }
        return shopCreditOrderDO;
    }

    @Override
    public void handleCreditExchange(String exchangeCode) {
        creditOrderMapper.exchange(exchangeCode);
    }

    @Override
    public int update(ShopOrderVO shopOrderVO) {
        ShopOrderDO shopOrderDO = backOrderMapper.selectByPrimaryKey(shopOrderVO.getId());
        if (shopOrderDO == null || shopOrderDO.getIsDelete() == 1) {
            throw new BusinessException("没有此订单！");
        }
        ShopOrderVO shopInfo = backOrderMapper.getDetailForPay(shopOrderDO.getOrderSn());
        if (shopInfo == null) {
            throw new BusinessException("没有此订单！");
        }
        BigDecimal buyCost = shopOrderDO.getBuyCost();
        BigDecimal payCost = shopOrderDO.getPayCost();
        BeanUtils.copyProperties(shopOrderVO, shopOrderDO);
        if (shopOrderVO.getBuyCost() != null && !shopOrderVO.getBuyCost().equals(buyCost)) {
            if (shopInfo.getShopPayStatus() != OrderConstants.OrderPayStatusEnum.PRE_PAY.getValue()) {
                throw new BusinessException("当前订单状态不允许修改下货商品总价！");
            }
            //修改进货总价，把价格和订单号都修改掉
            shopOrderDO.setOrderBackSn(OrderConstants.SnPrefix.BUY_SHOP.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(5));
        } else {
            shopOrderDO.setBuyCost(null);
        }
        if (shopOrderVO.getPayCost() != null && !shopOrderVO.getPayCost().equals(payCost)) {
            if (shopInfo.getPayStatus() != OrderConstants.OrderPayStatusEnum.PRE_PAY.getValue()) {
                throw new BusinessException("当前订单状态不允许修改实付价格！");
            }
            //修改实付金额，把价格和订单号都修改掉
            shopOrderDO.setPaySn(OrderConstants.SnPrefix.PAY_MEMBER.getValue() + DateUtils.dateTimeNow() + NumberUtils.generateCode(4));
        } else {
            shopOrderDO.setPayCost(null);
        }

        if (shopOrderVO.getOrderStatus() != null) {
            backShopOrderStatusMapper.updateOrderStatusByOrderId(shopOrderDO.getId(), shopOrderVO.getOrderStatus());
        }
        if (shopOrderVO.getPayStatus() != null) {
            backShopOrderStatusMapper.updatePayStatusByOrderId(shopOrderDO.getId(), shopOrderVO.getPayStatus());
        }
        if (shopOrderVO.getShopPayStatus() != null) {
            backShopOrderStatusMapper.updateBackPayStatusByOrderId(shopOrderDO.getId(), shopOrderVO.getShopPayStatus());
        }
        return backOrderMapper.updateByPrimaryKeySelective(shopOrderDO);
    }


    @Override
    @Transactional
    @Synchronized
    public void sendToMember(MemberGetCreditProductVO memberGetCreditProductVO) {
        //获取待赠送优惠券列表
        ShopProductSearchVO searchVO = new ShopProductSearchVO();
        searchVO.setIsEnable(1);
        searchVO.setIsDelete(0);
        searchVO.setSystemModule(SysConfigConstants.SystemModuleEnum.CREDIT.getValue());
        searchVO.setProductIdStr(memberGetCreditProductVO.getProductIdStr());
        String[] productIdArr = memberGetCreditProductVO.getProductIdStr().split(",");
        List<ShopProductVO> productList = backShopProductMapper.searchList(searchVO);
        if (productIdArr.length != productList.size()) {
            throw new BusinessException("存在不符合可赠送状态的积分商品，请刷新后重试！");
        }
        List<MemberDO> memberList = backMemberMapper.searchListByIdStr(memberGetCreditProductVO.getMemberIdStr());
        String[] memberIdArr = memberGetCreditProductVO.getMemberIdStr().split(",");
        if (memberIdArr.length != memberList.size()) {
            throw new BusinessException("存在不符合受赠状态的会员，请刷新后重试！");
        }
        List<Long> couponIdList = new ArrayList<>();
        List<HashMap<String, String>> smsNotifyParamList = new ArrayList<>();
        HashMap<String, String> existPhoneList = new HashMap<>();
        for (ShopProductVO productInfo : productList
        ) {
            if (productInfo.getStock() < memberIdArr.length) {
                throw new BusinessException("商品【" + productInfo.getProductName() + "】库存不足！");
            }
            for (MemberDO memberOne : memberList
            ) {
                ShopCreditOrderDO createDO = new ShopCreditOrderDO();
                createDO.setProductName(productInfo.getProductName());
                createDO.setMemberId(memberOne.getId());
                createDO.setShopId(memberOne.getId());
                createDO.setProductId(productInfo.getProductId());
                createDO.setProductCoverUrl(productInfo.getCoverUrl());
                createDO.setProductUnitPrice(productInfo.getPrice().intValue());
                createDO.setProductQuantity(1);
                createDO.setOrderCost(createDO.getProductUnitPrice() * createDO.getProductQuantity());
                createDO.setPayCost(0);
                String time = DateUtils.dateTimeNow();
                long orderId = 0L;
                try {
                    orderId = IdWorker.getFlowIdWorkerInstance().nextId();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                createDO.setId(orderId);
                createDO.setProductType(productInfo.getProductType());
                createDO.setOrderSn(OrderConstants.SnPrefix.PETROL.getValue() + time + NumberUtils.generateCode(5));
                createDO.setCreateTime(new Date());
                createDO.setCreateBy("平台赠送");
                //TODO:查看商品类型
                if (1 == productInfo.getProductType()) {
                    createDO.setExchangeCode(null);
                    createDO.setOrderStatus(OrderConstants.CreditOrderStatusEnum.USE.getValue());
                    //优惠券自动领取
                    couponIdList = backShopProductCouponLinkMapper.searchIdList(createDO.getShopId(), createDO.getProductId());
                    if (couponIdList.size() > 0) {
                        couponIdList.forEach(x -> {
                            MemberCouponDO memberCouponDO = new MemberCouponDO();
                            memberCouponDO.setCouponId(x);
                            memberCouponDO.setMemberId(createDO.getMemberId());
                            memberCouponDO.setMemberCouponStatus(CouponConstants.MemberCouponStatusEnum.NOT_USE.getValue());
                            memberCouponDO.setActivityId(0L);
                            memberCouponDO.setReceiveChannelDesc("来自：平台赠送兑换");
                            memberCouponDO.setCreateTime(new Date());
                            backMemberCouponMapper.insertSelective(memberCouponDO);
                        });
                    }
                } else {
                    createDO.setExchangeCode(NumberUtils.generateCode(8));
                    createDO.setOrderStatus(OrderConstants.CreditOrderStatusEnum.UN_USE.getValue());
                }
                //TODO:插入订单
                backCreditOrderMapper.insertSelective(createDO);
                //TODO:更新商品销量和库存
                backShopProductMapper.stockSubtraction(createDO.getProductId());
                backShopProductMapper.saleIncrement(createDO.getProductId());
                backShopProductMapper.shopSaleIncrement(createDO.getShopId(), createDO.getProductId());
                //TODO:短信消息写入
                if (!existPhoneList.containsKey(memberOne.getPhone()) && StringUtils.isNotEmpty(memberGetCreditProductVO.getTemplateCode())) {
                    HashMap<String, String> smsNotifyParam = new HashMap<>();
                    smsNotifyParam.put("templateKey", "giftReceive");
                    smsNotifyParam.put("smsCompany", "aliyun");
                    smsNotifyParam.put("templateCode", memberGetCreditProductVO.getTemplateCode());
                    smsNotifyParam.put("shopId", memberOne.getShopId().toString());
                    smsNotifyParam.put("phone", memberOne.getPhone());
                    smsNotifyParam.put("smsVar", productInfo.getProductName() + ",“" + LianLuSmsConstants.SignEnum.DEFAULT.getSign() + "”,山东省日照市东港区涛雏镇栈子村沿海路东(栈子村码头人口处)");
                    smsNotifyParamList.add(smsNotifyParam);
                    existPhoneList.put(memberOne.getPhone(), "1");
                }
            }
        }
        //批量短信通知
        for (HashMap<String, String> one : smsNotifyParamList
        ) {
            AsyncManager.me().execute(AsyncFactory.sendSmsNotify(one));
        }
        //刷新优惠券
        if (!couponIdList.isEmpty()) {
            AsyncManager.me().execute(AsyncFactory.refreshCoupon(String.join(",", couponIdList.stream().map(x -> x + "").collect(Collectors.toList()))));
        }
    }

    @Transactional
    public void rechargeHandle(MemberRechargeOrderDO createDO) {
        String time = DateUtils.dateTimeNow();
        HashMap<String, String> orderNotifyParam = new HashMap<>();//充值订单消息通知
        HashMap<String, String> balanceNotifyParam = new HashMap<>();//余额变动消息通知
        MemberDO memberInfo = backMemberMapper.selectByPrimaryKey(createDO.getMemberId());
        //TODO:获取会员余额
        BigDecimal newBalance = memberInfo.getBalance().add(createDO.getAmount());
        BigDecimal newTotalRechargeAmount = memberInfo.getTotalRechargeAmount().add(createDO.getAmount());
        Integer newCredit = memberInfo.getCredit() + createDO.getGiftCredit();
        //TODO:修改会员余额、累计充值金额、积分
        MemberDO memberUpdate = new MemberDO();
        memberUpdate.setId(createDO.getMemberId());
        memberUpdate.setBalance(newBalance);
        memberUpdate.setTotalRechargeAmount(newTotalRechargeAmount);
        memberUpdate.setCredit(newCredit);
        memberUpdate.setLastConsumeTime(new Date());
        backMemberMapper.updateByPrimaryKeySelective(memberUpdate);

        //TODO:修改商品销量
        if (0 != createDO.getProductId()) {
            backShopProductMapper.saleIncrement(createDO.getProductId());
            backShopProductMapper.shopSaleIncrement(createDO.getShopId(), createDO.getProductId());
        }

        //TODO:插入余额变动记录
        MemberBalanceRecordDO memberBalanceRecordDO = new MemberBalanceRecordDO();
        memberBalanceRecordDO.setShopId(createDO.getShopId());
        memberBalanceRecordDO.setRecordSn(OrderConstants.SnPrefix.BALANCE_MEMBER.getValue() + time + NumberUtils.generateCode(4));
        memberBalanceRecordDO.setType(MemberRechargeConstants.TypeEnum.SYSTEM_INSERT.getValue());
        memberBalanceRecordDO.setChangeType(MemberRechargeConstants.ChangeTypeEnum.INCREASE.getValue());
        memberBalanceRecordDO.setLinkModel(MemberRechargeConstants.LinkModelEnum.RECHARGE.getValue());
        memberBalanceRecordDO.setLinkSn(createDO.getOrderSn());
        memberBalanceRecordDO.setMemberId(createDO.getMemberId());
        memberBalanceRecordDO.setOldBalance(memberInfo.getBalance());
        memberBalanceRecordDO.setChangeBalance(createDO.getAmount());
        memberBalanceRecordDO.setNewBalance(newBalance);
        memberBalanceRecordDO.setRemark("后台充值成功,到账金额：" + createDO.getAmount() + "元");
        memberBalanceRecordDO.setCreateBy(ShiroUtils.getSysUser().getUserName());
        memberBalanceRecordDO.setCreateTime(new Date());
        backMemberBalanceRecordMapper.insertSelective(memberBalanceRecordDO);

        //余额变动-消息通知
        balanceNotifyParam.put("isInfo", "Y");
        balanceNotifyParam.put("templateKey", "balanceChange");
        balanceNotifyParam.put("shopId", memberBalanceRecordDO.getShopId().toString());
        balanceNotifyParam.put("linkModelDesc", MemberRechargeConstants.LinkModelEnum.RECHARGE.getValueDesc());
        balanceNotifyParam.put("linkSn", memberBalanceRecordDO.getLinkSn());
        balanceNotifyParam.put("changeBalance", "+" + memberBalanceRecordDO.getChangeBalance().toString());
        balanceNotifyParam.put("newBalance", memberBalanceRecordDO.getNewBalance().toString());
        balanceNotifyParam.put("createTime", DateUtils.getTime());
        balanceNotifyParam.put("balanceChangeRemark", memberBalanceRecordDO.getRemark());

        if (createDO.getGiftCredit() > 0) {
            //TODO:积分变动
            MemberCreditRecordDO memberCreditRecordDO = new MemberCreditRecordDO();
            memberCreditRecordDO.setShopId(createDO.getShopId());
            memberCreditRecordDO.setRecordSn(OrderConstants.SnPrefix.CREDIT_MEMBER.getValue() + time + NumberUtils.generateCode(4));
            memberCreditRecordDO.setType(MemberCreditConstants.TypeEnum.SYSTEM_INSERT.getValue());
            memberCreditRecordDO.setChangeType(MemberCreditConstants.ChangeTypeEnum.INCREASE.getValue());
            memberCreditRecordDO.setLinkModel(MemberCreditConstants.LinkModelEnum.RECHARGE.getValue());
            memberCreditRecordDO.setLinkSn(createDO.getOrderSn());
            memberCreditRecordDO.setMemberId(createDO.getMemberId());
            memberCreditRecordDO.setOldCredit(memberInfo.getCredit());
            memberCreditRecordDO.setChangeCredit(createDO.getGiftCredit());
            memberCreditRecordDO.setNewCredit(newCredit);
            memberCreditRecordDO.setRemark("后台充值赠送积分,充值:" + createDO.getAmount() + "元"
                    + "，赠送：" + createDO.getGiftCredit() + "分"
                    + "，充值单号：" + createDO.getOrderSn());
            memberCreditRecordDO.setCreateBy("会员充值赠送积分");
            memberCreditRecordDO.setCreateTime(new Date());
            backMemberCreditRecordMapper.insertSelective(memberCreditRecordDO);
            orderNotifyParam.put("creditRemark", "后台充值赠送" + createDO.getGiftCredit() + "积分");
        }

        //创建充值订单
        backMemberRechargeOrderMapper.insertSelective(createDO);

        //充值订单-消息通知
        orderNotifyParam.put("isInfo", "Y");
        orderNotifyParam.put("templateKey", "recharge");
        orderNotifyParam.put("orderSn", createDO.getOrderSn());
        orderNotifyParam.put("shopId", createDO.getShopId().toString());
        orderNotifyParam.put("orderStatusDesc", "后台充值成功");
        orderNotifyParam.put("amount", createDO.getAmount().toString() + "元");
        orderNotifyParam.put("payTime", DateUtils.getTime());
        orderNotifyParam.put("openid", memberInfo.getOpenid());
        orderNotifyParam.put("phone", memberInfo.getPhone());
        orderNotifyParam.put("smsVar", createDO.getAmount().toString() + "," + memberBalanceRecordDO.getNewBalance().toString());
        //微信模板通知
        AsyncManager.me().execute(AsyncFactory.sendWechatTemplateNotify(orderNotifyParam));
        if (balanceNotifyParam.containsKey("balanceChangeRemark")) {
            balanceNotifyParam.put("openid", memberInfo.getOpenid());
            AsyncManager.me().execute(AsyncFactory.sendWechatTemplateNotify(balanceNotifyParam));
        }
        //短信通知
        AsyncManager.me().execute(AsyncFactory.sendSmsNotify(orderNotifyParam));
    }
}

